// 题目描述
// 如果可以使用以下操作从一个字符串得到另一个字符串，则认为两个字符串 接近 ：

// 操作 1：交换任意两个 现有 字符。
// 例如，abcde -> aecdb
// 操作 2：将一个 现有 字符的每次出现转换为另一个 现有 字符，并对另一个字符执行相同的操作。
// 例如，aacabb -> bbcbaa（所有 a 转化为 b ，而所有的 b 转换为 a ）
// 你可以根据需要对任意一个字符串多次使用这两种操作。

// 给你两个字符串，word1 和 word2 。如果 word1 和 word2 接近 ，就返回 true ；否则，返回 false 。

 

// 示例 1：

// 输入：word1 = "abc", word2 = "bca"
// 输出：true
// 解释：2 次操作从 word1 获得 word2 。
// 执行操作 1："abc" -> "acb"
// 执行操作 1："acb" -> "bca"
// 示例 2：

// 输入：word1 = "a", word2 = "aa"
// 输出：false
// 解释：不管执行多少次操作，都无法从 word1 得到 word2 ，反之亦然。
// 示例 3：

// 输入：word1 = "cabbba", word2 = "abbccc"
// 输出：true
// 解释：3 次操作从 word1 获得 word2 。
// 执行操作 1："cabbba" -> "caabbb"
// 执行操作 2："caabbb" -> "baaccc"
// 执行操作 2："baaccc" -> "abbccc"

// 自己的答案：
/**
 * @param {string} word1
 * @param {string} word2
 * @return {boolean}
 */
var closeStrings = function (word1, word2) {
    // 1.种类相同 // Object.keys()
    // 2.每种数据相同 // Object.values()
    let word1Obj = {}
    let word2Obj = {}
    for (let i = 0; i < word1.length; i++) {
        // if (word1Obj[word1[i]] === undefined) {
        //     word1Obj[word1[i]] = 1
        // } else {
        //     word1Obj[word1[i]] += 1
        // }
        word1Obj[word1[i]] = (word1Obj[word1[i]] || 0) + 1
    }
    for (let i = 0; i < word2.length; i++) {
        // if (word2Obj[word2[i]] === undefined) {
        //     word2Obj[word2[i]] = 1
        // } else {
        //     word2Obj[word2[i]] += 1
        // }
        word2Obj[word2[i]] = (word2Obj[word2[i]] || 0) + 1
    }
    const arraysEqual = (a1, a2) => {
        return JSON.stringify(a1.sort()) === JSON.stringify(a2.sort());
    }
    return arraysEqual(Object.keys(word1Obj), Object.keys(word2Obj)) && arraysEqual(Object.values(word1Obj), Object.values(word2Obj))
};

// Gpt答案：
function areAlmostEqual(word1, word2) {
    // Step 1: Check if lengths are equal
    if (word1.length !== word2.length) {
        return false;
    }

    // Step 2: Check if character counts are the same
    const charCount1 = countCharacters(word1);
    const charCount2 = countCharacters(word2);

    if (Object.keys(charCount1).length !== Object.keys(charCount2).length) {
        return false;
    }

    for (const char in charCount1) {
        if (!(char in charCount2) || charCount1[char] !== charCount2[char]) {
            return false;
        }
    }

    // Step 3: Check if sorted strings are the same
    const sortedWord1 = word1.split('').sort().join('');
    const sortedWord2 = word2.split('').sort().join('');

    return sortedWord1 === sortedWord2;
}

// Helper function to count characters in a string
function countCharacters(str) {
    const charCount = {};
    for (const char of str) {
        charCount[char] = (charCount[char] || 0) + 1;
    }
    return charCount;
}

// Test cases
console.log(areAlmostEqual("abc", "bca")); // true
console.log(areAlmostEqual("a", "aa")); // false
console.log(areAlmostEqual("cabbba", "abbccc")); // true

// 官方题解：
var closeStrings = function(word1, word2) {
    let count1 = new Array(26).fill(0), count2 = new Array(26).fill(0);
    for (let i = 0; i < word1.length; i++) {
        count1[word1.charCodeAt(i) - 97]++;
    }
    for (let i = 0; i < word2.length; i++) {
        count2[word2.charCodeAt(i) - 97]++;
    }
    for (let i = 0; i < 26; i++) {
        if (count1[i] > 0 && count2[i] == 0 || count1[i] == 0 && count2[i] > 0) {
            return false;
        }
    }
    count1.sort();
    count2.sort();
    return count1.toString() == count2.toString();
};